package threads.producer.consumer;

/**
 * 商店类
 * <p>
 * wait(), notify() 与 notifyAll() 是 Object 定义的方法, 可以通过这3个方法控制线程是否对象的锁定,或者通知线程参与锁定竞争。
 */
public class Store {

    // 商店持有的商品
    private String product;

    // 接收商品
    public synchronized void setProduct(String product) throws InterruptedException {
        // 有商品则等待(不接收)
        waitIfExists();

        // 接收商品
        System.out.println("商店进新品： " + product);
        this.product = product;

        // 通知等待的线程（例如消费者）
        notify();
    }

    // 如果商店有商品则等待
    private synchronized void waitIfExists() throws InterruptedException {
        while (null != this.product) wait();
    }

    // 卖出商品
    public synchronized String getProduct() throws InterruptedException {
        // 没有商品卖等待
        waitIfEmpty();

        // 卖出商品
//        System.out.println("已卖出商品： " + product);
        String rst = product;
        this.product = null;

        // 通知等待线程（例如生产者）
        notify();

        return rst;
    }

    // 如果商店没有商品则等待
    private synchronized void waitIfEmpty() throws InterruptedException {
        while (null == this.product) wait();
    }

}
